CA65 ?= ca65
LD65 ?= ld65
PYTHON ?= python3
TOOLS  ?= ../../_tools

all: reconstructed.nes verify

prg.o: prg.s symbols.inc locals.inc
	$(CA65) -g -o $@ $<

header.o: header.s header.bin
	$(CA65) -g -o $@ $<

chr.o: chr.s chr.bin
	$(CA65) -g -o $@ $<

reconstructed.nes: header.o prg.o chr.o linker.cfg
	$(LD65) -C linker.cfg -m reconstructed.map -Ln reconstructed.lbl -o $@ header.o prg.o chr.o

verify: reconstructed.nes rom.nes
	cmp reconstructed.nes rom.nes
	@echo "Byte-identical ROM verified."

# Regenerate prg.s and locals.inc from prg.bin, then re-apply the naming.
# Every --table/--extra-seed flag below is a documented classification
# decision, not a convenience; see the provenance block at the head of prg.s.
#
#   --table 0xC3A6:9,0xCCD5:8  the two queued-event dispatchers, whose
#                               16-bit vector tables hold the handler
#                               addresses the engine jumps to
#   --extra-seed                 the sixteen targets of the four `jmp`
#                               trampoline tables the tracer cannot see
#                               ($C01E, $C02A, $C042, $C054), the $C800
#                               boot mainline, and six further code starts
#                               found by inspection
regen: pass1 pass2 pass3

pass1:
	$(PYTHON) $(TOOLS)/nesdis.py --prg prg.bin --base 0xC000 --project "Pyramid (U) (Sachen)" \
	    --out prg.s --locals locals.inc --auto-seed \
	    --table "0xC3A6:9,0xCCD5:8" \
	    --extra-seed "0xC800,0xC1C9,0xC1D0,0xC1D7,0xC1EF,0xC205,0xC201,0xC225,0xC23A,0xC294,0xC34A,0xC43E,0xC585,0xC5AB,0xC614,0xC662,0xC6A3,0xD79D,0xD7D7,0xD7EB,0xDF89,0xF942,0xFF74"
	cat zp_aliases.inc >> locals.inc

# Pass 2: the routine and branch-target names, then the zero-page aliases
# at the sites where their role is proven.
pass2: pass1
	$(PYTHON) $(TOOLS)/apply_pass2_map.py . routinemap.tsv --write
	$(PYTHON) $(TOOLS)/apply_zp_aliases.py . \
	    --alias ScriptPtrLo=Zp02 --alias ScriptPtrHi=Zp03 --alias CommandListFlag=Zp04 \
	    --alias VramPosHi=Zp05 --alias VramPosLo=Zp06 --alias FrameCounter=Zp0A \
	    --alias FrameCounterHi=Zp0B --alias DrawCounter=Zp0C \
	    --alias SoundTickScriptLo=Zp27 --alias SoundTickScriptHi=Zp28 \
	    --alias SoundPlayer1ScriptLo=Zp29 --alias SoundPlayer1ScriptHi=Zp2A \
	    --alias SoundPlayer2ScriptLo=Zp2B --alias SoundPlayer2ScriptHi=Zp2C \
	    --alias SoundPlayer3ScriptLo=Zp2D --alias SoundPlayer3ScriptHi=Zp2E \
	    --alias Player1Input=Zp3D --alias Player2Input=Zp3E \
	    --alias SpriteX=Zp43 --alias SpriteY=Zp44 \
	    --alias DeltaLo=Zp4D --alias DeltaMid=Zp4E --alias DeltaHi=Zp4F \
	    --alias DeltaWrapCount=Zp50 \
	    --at-ind 'ScriptPtrLo@C3A3' --at-ind 'ScriptPtrLo@CCCA' --write

# Pass 3: name the data blocks, apply the hardware register names, and put
# the audit comments back in their canonical column.
pass3: pass2
	$(PYTHON) $(TOOLS)/name_data_region.py . $$(awk -F'\t' '!/^#/ && NF>1 {printf "%s=%s ", $$1, $$2}' data_region_names.tsv) --write
	$(PYTHON) $(TOOLS)/apply_symbols.py . --write
	$(PYTHON) $(TOOLS)/align_audit_comments.py . --write

clean:
	rm -f *.o reconstructed.nes reconstructed_prg.bin reconstructed.map reconstructed.lbl

.PHONY: all verify clean regen pass1 pass2 pass3
